package com.bee.bootstrap.formDesign.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.bee.bootstrap.formDesign.entity.FormData;
import com.bee.bootstrap.formDesign.entity.FormRecord;
import com.bee.bootstrap.formDesign.mapper.FormRecordMapper;
import com.bee.bootstrap.formDesign.service.IFormDataService;
import com.bee.bootstrap.formDesign.service.IFormRecordService;
import com.bee.bootstrap.system.entity.Attachment;
import com.bee.bootstrap.system.entity.Dictionary;
import com.bee.bootstrap.system.service.IAttachmentService;
import com.bee.bootstrap.system.service.IDictionaryService;
import com.bee.common.core.enums.FormElementEnum;
import com.bee.common.core.enums.StatusEnum;
import com.bee.common.core.result.Result;
import com.bee.common.tools.context.SpringContextUtil;
import com.bee.common.tools.date.DateUtils;
import net.sf.json.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Transformer;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author liekkas
 * @since 2018-08-26
 */
@Service
public class FormRecordServiceImpl extends ServiceImpl<FormRecordMapper, FormRecord> implements IFormRecordService {

    @Autowired
    private IFormDataService formDataServiceImpl;
    @Autowired
    private IAttachmentService attachmentServiceImpl;
    @Autowired
    private IDictionaryService dictionaryServiceImpl;

    @Override
    public Result addFormRecord(FormRecord formRecord) {
        formRecord.setCreateTime(new Date());
        formRecord.setStatus(StatusEnum.NORMAL.toString());
        formRecord.setCreateUserId(Long.valueOf(SpringContextUtil.getRequest().getAttribute("userId").toString()));
        this.insert(formRecord);
        if(formRecord.getFormDataView()==null||formRecord.getFormDataView().size()==0)
            return Result.fail("失败");
        formRecord.getFormDataView().forEach(FormData->{
            FormData.setFormRecordId(formRecord.getId());
        });
        formDataServiceImpl.insertBatch(formRecord.getFormDataView());
        return Result.success("成功");
    }

    @Override
    public Result findOneFormRecordData(Long formRecordId) {
        List<FormData> formDataList=formDataServiceImpl.selectList(new EntityWrapper<FormData>()
                .eq("form_record_id",formRecordId));
        formDataList.forEach(formData -> {
            if(FormElementEnum.uploads.toString().equals(formData.getElement())){
                List<Long> ids =new ArrayList<Long>();
                String[] strings=formData.getValue().split(",");
                for(String str:strings){
                    ids.add(Long.valueOf(str));
                }
                List<Attachment> list=attachmentServiceImpl.findAttachmentsById(ids);
                formData.setValueView(list);
            }else if(Arrays.asList(FormElementEnum.cascader,FormElementEnum.checkbox,FormElementEnum.address).contains(FormElementEnum.valueOf(formData.getElement()))){
                formData.setValueView(Arrays.asList(formData.getValue().split(",")));
            }else{
                formData.setValueView(formData.getValue());
            }
        });
        return Result.success(formDataList);
    }

    @Override
    public Result findFormRecordAndData(Long templateId,Page<FormRecord>page,String formRecordQuery) {
        //先获取templateId下的数据
        List<FormRecord> formRecords=this.selectList(new EntityWrapper<FormRecord>().eq("form_template_id",templateId).eq("status",StatusEnum.NORMAL.toString()));
        //查询条件集合
        List<FormData> query=new ArrayList<>();
        if(StringUtils.isNotBlank(formRecordQuery)){
            Map classMap=new HashMap();
            classMap.put("formDataView", FormData.class);
            FormRecord record= (FormRecord) JSONObject.toBean(JSONObject.fromObject(formRecordQuery),FormRecord.class,classMap);
            if(record.getFormDataView()!=null&&record.getFormDataView().size()>0){
                query=record.getFormDataView();
            }
        }
        //过滤条件后的formRecordId和最终数据
        List<Long> queryFormRecordIds=new ArrayList<>();
        List<FormRecord> result=new ArrayList<>();
        //开始过滤查询数据
        if(formRecords!=null&&formRecords.size()>0){
            List<Long> recordIds=new ArrayList<>();
            formRecords.forEach(formRecord -> {
                recordIds.add(formRecord.getId());
            });
            EntityWrapper<FormData> entityWrapper=new EntityWrapper<FormData>();
            //查询条件
            if(query.size()>0){
                Set<String> names=new HashSet<>();
                Set<String> values=new HashSet<>();
                for(FormData formData:query){
                    names.add(formData.getName());
                    //时间组件需要格式化数据
                    if(FormElementEnum.datepicker.toString().equals(formData.getElement())){
                        values.add(DateUtils.parseUtcDate(formData.getValue(),formData.getAdditional()));
                    }else{
                        values.add(formData.getValue());
                    }
                }
                //查询的结果（部分formRecordId会不存在）
                List<FormData> subList=formDataServiceImpl.selectList(new EntityWrapper().in("name",names)
                        .in("value",values).in("form_record_id",recordIds).orderBy("form_record_id"));
                List<FormData> filter=new ArrayList<>();
                //包含所有查询条件的数据
                if(subList!=null&&subList.size()>0){
                    //分组
                    Map<Long, List<FormData>> collect = subList.stream()
                            .collect(Collectors.groupingBy(FormData::getFormRecordId));
                    for(List<FormData> value:collect.values()){
                        //判断是否满足所有条件
                        if(query.size()==value.size()){
                            filter.addAll(value);
                        }
                    }
                }
                Set<Long> formRecordIds=new HashSet<Long>();
                if(filter!=null&&filter.size()>0){
                    filter.forEach(formData -> {
                        formRecordIds.add(formData.getFormRecordId());
                    });
                }
                //存在查询条件取formRecords和formDatas的共同formRecordId才是最终的数据
                for(Long all:recordIds){
                    for(Long id:formRecordIds){
                        if(id.compareTo(all)==0){
                            queryFormRecordIds.add(id);
                        }
                    }
                }
            }else{
                queryFormRecordIds=recordIds;
            }
            if(queryFormRecordIds.size()==0){
                 page.setRecords(result);
                 page.setTotal(0);
                 return Result.success(page);
            }
            //合并完id查找分页数据
            page=this.selectPage(page,new EntityWrapper<FormRecord>().in("id",queryFormRecordIds).orderBy("create_time",false));
            //分页的查询数据
            List<Long> computeId=new ArrayList<>();
            page.getRecords().forEach(formRecord -> {
                computeId.add(formRecord.getId());
            });
            entityWrapper.in("form_record_id",computeId).orderBy("form_record_id");
            List<FormData> formDatas=formDataServiceImpl.selectList(entityWrapper);
            //转化数据字典和附件表数据
            Set<Long> dictionaryIds=new HashSet<Long>();
            Set<Long> attachmentIds=new HashSet<Long>();
            formDatas.forEach(formData -> {
                //数据字典组件
                if(Arrays.asList(FormElementEnum.checkbox,FormElementEnum.radio,FormElementEnum.select).contains(
                        FormElementEnum.valueOf(formData.getElement()))&&formData.getDictionaryId()!=null){
                    dictionaryIds.add(formData.getDictionaryId());
                }
                //上传附件组件
                if(FormElementEnum.uploads.toString().equals(formData.getElement())){
                    List<Long> ids=new ArrayList<Long>();
                    CollectionUtils.collect(Arrays.asList( formData.getValue().split(",")),
                            new Transformer(){
                                public java.lang.Object transform(java.lang.Object input){
                                    return new Long((String)input);
                                }
                            } ,ids );
                    attachmentIds.addAll(ids);
                }
            });
            List<Dictionary> dictionaries=dictionaryServiceImpl.selectFormTypeDictionarySub(dictionaryIds);
            List<Attachment> attachments=attachmentServiceImpl.findAttachmentsById(attachmentIds);

            /*if(formRecords.size()!=queryFormRecordIds.size()){
                //去除查询条件后的formRcord
                for(FormRecord formRecord:formRecords){
                    for(Long id:queryFormRecordIds){
                        if(formRecord.getId().compareTo(id)==0){
                            result.add(formRecord);
                        }
                    }
                }
            }else{
                result=formRecords;
            }*/
            result=page.getRecords();
            for(int i=0;i<result.size();i++){
                List<FormData> data=new ArrayList<FormData>();
                for(int j=0;j<formDatas.size();j++){
                    if(formDatas.get(j).getFormRecordId().compareTo(result.get(i).getId())==0){
                        data.add(formDatas.get(j));
                        //数据转换
                        switch (formDatas.get(j).getElement()){
                            case "radio":
                            case "select":{
                                Dictionary dictionary=dictionaryServiceImpl.findByParentAndValue(dictionaries,formDatas.get(j).getDictionaryId(),formDatas.get(j).getValue());
                                formDatas.get(j).setValueView(dictionary!=null?dictionary.getName():"");
                            }
                            break;
                            case "checkbox":{
                                List<String> values=new ArrayList<>();
                                List<Dictionary> checkBoxDictionaries=dictionaryServiceImpl.findCheckBoxElement(dictionaries,formDatas.get(j).getDictionaryId(),formDatas.get(j).getValue());
                                if(checkBoxDictionaries!=null&&checkBoxDictionaries.size()>0){
                                    checkBoxDictionaries.forEach(dictionary -> {
                                        values.add(dictionary.getName());
                                    });
                                }
                                formDatas.get(j).setValueView(values);
                            }
                            break;
                            case "cascader":{
                                formDatas.get(j).setValueView(StringUtils.isNotBlank(formDatas.get(j).getValue())?
                                        Arrays.asList(formDatas.get(j).getValue().split(",")):"");
                            }
                            break;
                            case "uploads":{ //上次组件
                                List<Attachment> valueViews=attachmentServiceImpl.findAttachmentsByIds(attachments,formDatas.get(j).getValue());
                                formDatas.get(j).setValueView(valueViews);
                            }
                            break;
                            default:
                                formDatas.get(j).setValueView(formDatas.get(j).getValue());
                        }
                    }
                }
                result.get(i).setFormDataView(data);
            }
        }
        return Result.success(page);
    }

    @Override
    public Result deleteFormRecordCascade(Long id) {
        FormRecord formRecord=this.selectById(id);
        formRecord.setStatus(StatusEnum.INVALID.toString());
        formRecord.setUpdateTime(new Date());
        this.updateById(formRecord);
        List<FormData> formDatas=formDataServiceImpl.findByFormRecordId(id);
        List<Long> ids=new ArrayList<>();
        if(formDatas!=null&&formDatas.size()>0){
            formDatas.forEach(formData -> {
                ids.add(formData.getId());
            });
            formDataServiceImpl.deleteBatchIds(ids);
        }
        return Result.success("删除记录成功");
    }

    @Override
    public Result updateFormReocrdAndData(FormRecord formRecord) {
        formRecord.setUpdateTime(new Date());
        formRecord.setStatus(StatusEnum.NORMAL.toString());
        this.updateById(formRecord);
        List<FormData> formData=formRecord.getFormDataView();
        formDataServiceImpl.insertOrUpdateBatch(formData);
        return Result.success("更新成功");

    }

}
